﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.ComponentModel;
using System.Drawing;
using NetJsWire.Lite.Converters;
using Newtonsoft.Json;

namespace NetJsWire.Lite.Widgets.UI.Form
{
    [JsonObject( MemberSerialization = MemberSerialization.OptIn )]
    public abstract class FieldLW : BoxComponent
    {
        internal const object Undefined = null;
        private string _invalidText = "The value in this field is invalid";
        private object _value;

        protected FieldLW()
            : this( null )
        {
        }

        protected FieldLW( IContainer container )
            : base( container )
        {
            base.Xtype = "field";
        }

        [JsonProperty( "name", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore )]
        [DefaultValue( ( string ) null )]
        [Description( "The field's HTML name attribute (defaults to ''). Note: this property must be set if this field is to be automatically included with form submit()." )]
        public string ClientName { get; set; }

        [JsonProperty( "readOnly", DefaultValueHandling = DefaultValueHandling.Ignore )]
        [DefaultValue( false )]
        [Description( "true to mark the field as readOnly in HTML." )]
        public virtual bool ReadOnly { get; set; }

        [Browsable( true )]
        [JsonProperty( "invalidText", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore )]
        [DefaultValue( "The value in this field is invalid" )]
        [Description( "The error text to use when marking a field invalid and no message is provided (defaults to 'The value in this field is invalid')" )]
        public virtual string InvalidText
        {
            get { return _invalidText; }
            set { _invalidText = value; }
        }

        /// <summary>
        ///   The default CSS class for the field (defaults to 'x-form-field')
        /// </summary>
        [JsonProperty( "fieldClass", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore )]
        [Description( "The default CSS class for the field (defaults to 'x-form-field')" )]
        public virtual string FieldClass { get; set; }

        /// <summary>
        ///   The type attribute for input fields -- e.g. radio, text, password, file (defaults to 'text'). The types 'file' and 'password' must be used to render those field types currently -- there are
        ///   no separate Ext components for those.
        ///   Note that if you use <tt>inputType:'file'</tt>, {@link #emptyText} is not supported and should be avoided.
        /// </summary>
        [JsonProperty( "inputType", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore )]
        [Description( "The type attribute for input fields -- e.g. radio, text, password, file (defaults to 'text'). The types 'file' and 'password' must be used to render those field types currently -- there are no separate Ext components for those." )]
        public string InputType { get; set; }

        /// <summary>
        ///   The tabIndex for this field. 
        ///   Note this only applies to fields that are rendered,not those which are built via applyTo (defaults to undefined).
        /// </summary>
        [JsonProperty( "tabIndex", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore )]
        [DefaultValue( null )]
        [Description( "The tabIndex for this field." )]
        public new int? TabIndex { get; set; }

        /// <summary>
        ///   A value to initialize this field with (defaults to undefined).
        /// </summary>
        [JsonProperty( "value", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore )]
        [TypeConverter( typeof( StringConverter ) )]
        [Description( "A value to initialize this field with." )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        public virtual object Value
        {
            get { return _value; }
            set
            {
                _value = value;
                if ( Site != null && Site.DesignMode )
                    InvalidateWindow();
            }
        }

        [Browsable( false )]
        public override Color BackColor
        {
            get
            {
                return Parent != null ? Parent.BackColor : base.BackColor;
            }
            set
            {
                base.BackColor = value;
            }
        }

        public bool ShouldSerializeClientName()
        {
            return !string.IsNullOrWhiteSpace( ClientName );
        }

        protected void ResetClientName()
        {
            ClientName = null;
        }

        public bool ShouldSerializeInvalidText()
        {
            return !string.IsNullOrWhiteSpace( InvalidText ) && InvalidText != "The value in this field is invalid";
        }

        protected void ResetInvalidText()
        {
            InvalidText = "The value in this field is invalid";
        }

        public bool ShouldSerializeInputType()
        {
            return !string.IsNullOrWhiteSpace( InputType );
        }

        protected void ResetInputType()
        {
            InputType = null;
        }

        public bool ShouldSerializeValue()
        {
            return Value != null && !string.IsNullOrWhiteSpace( Value.ToString() );
        }

        protected void ResetValue()
        {
            Value = null;
        }

        public bool ShouldSerializeTabIndex()
        {
            return TabIndex != null && TabIndex > 0;

        }

        protected void ResetTabIndex()
        {
            TabIndex = null;
        }
    }
}
